package com.dragon.modules.yuegou.service.impl.member;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.modules.yuegou.entity.member.DistrictMemberEntity;
import com.dragon.modules.yuegou.enums.code.DistrictCode;
import com.dragon.modules.yuegou.enums.code.ErrorCode;
import com.dragon.modules.yuegou.enums.code.PayCode;
import com.dragon.modules.yuegou.enums.code.PointsCode;
import com.dragon.modules.yuegou.enums.points.DetailIncomeExpenses;
import com.dragon.modules.yuegou.enums.points.DetailSource;
import com.dragon.modules.yuegou.enums.points.DetailType;
import com.dragon.modules.yuegou.mapper.member.DistrictMemberMapper;
import com.dragon.modules.yuegou.model.member.DistrictMember;
import com.dragon.modules.yuegou.model.member.Level;
import com.dragon.modules.yuegou.model.order.Order;
import com.dragon.modules.yuegou.model.points.Detail;
import com.dragon.modules.yuegou.query.member.DistrictMemberQuery;
import com.dragon.modules.yuegou.service.busd.DistrictService;
import com.dragon.modules.yuegou.service.member.DistrictMemberService;
import com.dragon.modules.yuegou.service.member.LevelService;
import com.dragon.modules.yuegou.service.member.MemberCardLevelService;
import com.dragon.modules.yuegou.service.points.DetailService;
import com.dragon.modules.yuegou.web.Check;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * 商圈会员 服务实现
 *
 * @author pbuilder generated
 * @date 2019-03-19 08:59:40
 * @version 2.0
 */
@Slf4j
@Service("memDistrictMemberService")
public class DistrictMemberServiceImpl
		extends ServiceImpl<DistrictMemberMapper, DistrictMemberEntity>
		implements DistrictMemberService {

	@Autowired
	private LevelService levelService;

	@Autowired
	private MemberCardLevelService memberCardLevelService;

	@Autowired
	private DistrictService districtService;

	@Autowired
	private DetailService detailService;

	@Override
	public DistrictMember createDistrictMember(String memberId, String busdId) {
		districtService.checkBusdId(busdId);
		Check.notNull(memberId, PayCode.MEMBERID_IS_EMPTY.getMessage());

		DistrictMemberQuery query = new DistrictMemberQuery();
		query.setMemberId(memberId);
		query.setBusdId(busdId);
		List<DistrictMemberEntity> districtMemberList = list(query.toQueryWrapper());
		if (CollectionUtils.isNotEmpty(districtMemberList)) {
			return new DistrictMember(districtMemberList.get(0));
		} else {
			DistrictMember districtMember = new DistrictMember();
			districtMember.setBusdId(busdId);
			districtMember.setMemberId(memberId);
			districtMember.setMemPoints(0);
			districtMember.setCumulativePoints(0);
			districtMember.setOnlinePoints(0);
			districtMember.setTotalPoints(0);
			districtMember.setSignday(0);
			districtMember.setFansNum(0);
			// 会员等级
			Level level = levelService.getLowestLevel(busdId);
			if (level != null) {
				districtMember.setMemLevel(level.getId());
				districtMember.setValidityBeginTime(LocalDateTime.now());
				districtMember.setValidityEndTime(levelService.getValidityEndTime(districtMember.getValidityBeginTime(), level.getCycle()));
			}
			baseMapper.insert(districtMember);
			try {
				districtMember.setNewMember(true);

				memberCardLevelService.initMemberCardLevel(memberId, memberId);
			}catch (Exception e){
				//创建时会有可能会存在重复会员，报错之后重新查询

				query = new DistrictMemberQuery();
				query.setMemberId(memberId);
				query.setBusdId(busdId);
				districtMemberList = list(query.toQueryWrapper());
				if (CollectionUtils.isNotEmpty(districtMemberList)) {
					return new DistrictMember(districtMemberList.get(0));
				}
			}

			return districtMember;
		}
	}

	@Override
	public void pointOrder(Order order, DetailSource source) {
		Check.notNull(order, "order is required");
		Check.notNull(source, "来源 is required");
		Check.notEmpty(order.getBuyerId(), "memberId is required");
		Check.notEmpty(order.getId(), "orderNo is required");
		Check.notEmpty(order.getBusdId(), DistrictCode.BUSDID_IS_EMPTY.getMessage());
		Check.notNull(order.getPoints(), "fee is required");
		log.debug("会员使用积分支付开始====== 参数={}", order.getId());
		DistrictMember districtMember = createDistrictMember(order.getBuyerId(), order.getBusdId());
		if (districtMember.getMemPoints() < order.getPoints()) {
			throw new DragonException(PointsCode.POINTS_INSUFFICIENT);
		}

		// 修改积分
		DistrictMember updateDistrictMember = new DistrictMember();
		updateDistrictMember.setMemPoints(districtMember.getMemPoints() - order.getPoints());
		updateDistrictMember.setVersion(districtMember.getVersion() + 1);

		DistrictMemberQuery member = new DistrictMemberQuery();
		member.setId(districtMember.getId());
		member.setVersion(districtMember.getVersion());

		if (baseMapper.update(updateDistrictMember, member.toQueryWrapper()) == 1) {
			// 插入积分明细
			Detail detail = new Detail();
			detail.busdId(order.getBusdId());
			detail.setMemberId(order.getBuyerId());
			detail.setType(DetailType.MALL);
			detail.setSource(source);
			detail.setMerchantId(order.getMerchantId());
			detail.setIncomeExpenses(DetailIncomeExpenses.EXPENSES);
			detail.setPoints(order.getPoints());
			detail.setDel(false);
			detailService.save(detail);
		}
	}

	@Override
	public void cancelOrder(Order order) {
		Check.notNull(order, "order is required");
		Check.notEmpty(order.getBuyerId(), "memberId is required");
		Check.notEmpty(order.getId(), "orderNo is required");
		Check.notEmpty(order.getBusdId(), DistrictCode.BUSDID_IS_EMPTY.getMessage());
		Check.notNull(order.getPoints(), "fee is required");
		DistrictMember districtMember = createDistrictMember(order.getBuyerId(), order.getBusdId());

		// 修改积分
		DistrictMember updateDistrictMember = new DistrictMember();
		updateDistrictMember.setMemPoints(districtMember.getMemPoints() + order.getPoints());
		updateDistrictMember.setVersion(districtMember.getVersion() + 1);

		DistrictMemberQuery member = new DistrictMemberQuery();
		member.setId(districtMember.getId());
		member.setVersion(districtMember.getVersion());

		if (baseMapper.update(updateDistrictMember, member.toQueryWrapper()) == 1) {
			// 插入积分明细
			Detail detail = new Detail();
			detail.busdId(order.getBusdId());
			detail.setMemberId(order.getBuyerId());
			detail.setMerchantId(order.getMerchantId());
			detail.setType(DetailType.MALL);
			detail.setSource(DetailSource.CANCEL);
			detail.setIncomeExpenses(DetailIncomeExpenses.INCOME);
			detail.setPoints(order.getPoints());
			detail.setDel(false);
			detailService.save(detail);
		}

	}

	@Override
	public Boolean modifyDistrictMemberPoints(String busdId, String memberId, String merchantId, Integer points, DetailType detailType,
			DetailSource detailSource) {
		Check.notNull(busdId, DistrictCode.DISTRICT_NOTNULL.getMessage());
		Check.notNull(memberId, "会员id缺失");
		DistrictMemberQuery districtMemberQuery = new DistrictMemberQuery();
		districtMemberQuery.setBusdId(busdId);
		districtMemberQuery.setMemberId(memberId);

		List<DistrictMemberEntity> districtMemberList = list(districtMemberQuery.toQueryWrapper());
		DistrictMemberEntity districtMember = districtMemberList.get(0);
		// 如果point大于0，直接修改会员积分和累计积
		districtMember.setMemPoints((districtMember.getMemPoints() + points) > 0 ? (districtMember.getMemPoints() + points) : 0);
		if(DetailType.ONLINESHOP.equals(detailType)) {
			districtMember.setOnlinePoints(points > 0 ? (districtMember.getOnlinePoints() + points) : districtMember.getOnlinePoints());
		}else {
			districtMember.setCumulativePoints(points > 0 ? (districtMember.getCumulativePoints() + points) : districtMember.getCumulativePoints());
		}
		districtMember.setTotalPoints(points > 0 ? (districtMember.getTotalPoints() + points) : districtMember.getTotalPoints());
		// 修改以后版本号+1
		districtMemberQuery.setVersion(districtMember.getVersion());
		districtMemberQuery.setId(districtMember.getId());
		districtMember.setVersion(districtMember.getVersion() + 1);
		if (baseMapper.update(districtMember, districtMemberQuery.toQueryWrapper()) > 0) {
			Detail detail = new Detail();
			detail.setBusdId(busdId);
			detail.setMemberId(memberId);
			detail.setType(detailType);
			detail.setMerchantId(merchantId);
			detail.setSource(detailSource);
			detail.setIncomeExpenses(points < 0 ? DetailIncomeExpenses.EXPENSES : DetailIncomeExpenses.INCOME);
			detail.setPoints(points);
			detailService.save(detail);
			return true;
		}
		return false;
	}

	// 添加积分详情
	public void addPointDetail(String busdId, String memberId, Integer points) {
		Detail detail = new Detail();
		detail.setBusdId(busdId);
		detail.setMemberId(memberId);
		detail.setType(DetailType.IMPORTS);
		detail.setSource(DetailSource.CRM);
		detail.setIncomeExpenses(points < 0 ? DetailIncomeExpenses.EXPENSES : DetailIncomeExpenses.INCOME);
		detail.setPoints(points);
		detailService.save(detail);
	}

	@Override
	public String getMemberLevelId(String memberId, String busdId) {
		Check.notNull(memberId, "会员id is required");
		Check.notNull(busdId, DistrictCode.BUSDID_IS_EMPTY.getMessage());

		DistrictMemberQuery query = new DistrictMemberQuery();
		query.setBusdId(busdId);
		query.setMemberId(memberId);
		DistrictMemberEntity districtMember = getOne(query.toQueryWrapper());

		if (districtMember == null || StringUtils.isNotEmpty(districtMember.getId())) {
			districtMember = createDistrictMember(memberId, busdId);
		}

		if (districtMember != null && StringUtils.isNotEmpty(districtMember.getMemLevel())) {
			return districtMember.getMemLevel();
		}

		// 商圈会员没有等级 默认为商圈第一个等级
		Level level = levelService.getLowestLevel(busdId);
		if (level != null && StringUtils.isNotEmpty(level.getId())) {
			districtMember.setMemLevel(level.getId());
			districtMember.setValidityBeginTime(LocalDateTime.now());
			districtMember.setValidityEndTime(
					levelService.getValidityEndTime(districtMember.getValidityBeginTime(), level.getCycle()));
			baseMapper.updateById(districtMember);
			return level.getId();
		}
		return null;
	}

	@Override
	public Level getMemberLevel(String memberId, String busdId) {
		Check.notNull(memberId, "会员id is required");
		Check.notNull(busdId, DistrictCode.BUSDID_IS_EMPTY.getMessage());

		DistrictMemberQuery query = new DistrictMemberQuery();
		query.setBusdId(busdId);
		query.setMemberId(memberId);
		DistrictMemberEntity districtMember = getOne(query.toQueryWrapper());

		if (districtMember == null || StringUtils.isEmpty(districtMember.getId())) {
			districtMember = this.createDistrictMember(memberId,busdId);
		}

		if (districtMember != null && StringUtils.isNotEmpty(districtMember.getMemLevel())) {
			return new Level(levelService.getById(districtMember.getMemLevel()));
		}

		// 商圈会员没有等级 默认为商圈第一个等级
		Level level = levelService.getLowestLevel(busdId);
		if (level != null && StringUtils.isNotEmpty(level.getId())) {
			districtMember.setMemLevel(level.getId());
			districtMember.setValidityBeginTime(LocalDateTime.now());
			districtMember.setValidityEndTime(
					levelService.getValidityEndTime(districtMember.getValidityBeginTime(), level.getCycle()));
			baseMapper.updateById(districtMember);
			return level;
		}

		return null;
	}

	@Override
	public void neatenMemberPointsTask() {
		List<Detail> details = detailService.searchTheAll();
		details.forEach(detail -> {
			try {
				neatenMemberPoints(detail);
			} catch (Exception e) {
				log.error("积分整理任务执行失败；会员id={}，商圈id={}", detail.getMemberId(), detail.getBusdId(), e);
			}
		});

	}

	@Override
	public void changePoints(String busdId, String buyerId, Integer integral) {
		if (baseMapper.changePoints(busdId,buyerId,integral) > 0){
			Detail detail = new Detail();
			detail.busdId(busdId);
			detail.setMemberId(buyerId);
			detail.setType(DetailType.PARK);
			detail.setSource(DetailSource.PARK);
			detail.setIncomeExpenses(DetailIncomeExpenses.EXPENSES);
			detail.setPoints(integral);
			detail.setDel(false);
			detailService.save(detail);
		}
	}

	/**
	 * 单个商圈会员累计积分整理
	 * 
	 * @param detail
	 */
	private void neatenMemberPoints(Detail detail) {
		DistrictMemberQuery query = new DistrictMemberQuery();
		query.setBusdId(detail.getBusdId());
		query.setMemberId(detail.getMemberId());
		DistrictMemberEntity districtMember = getOne(query.toQueryWrapper());
		if (Objects.nonNull(districtMember) && detail.getPoints() != districtMember.getCumulativePoints()) {
			log.debug("累计积分与计算不一致,原累计积分={}，现累计积分={}，会员id={}，商圈id={}", districtMember.getCumulativePoints(),
					detail.getPoints(), districtMember.getMemberId(), districtMember.getBusdId());
			districtMember.setCumulativePoints(detail.getPoints()- districtMember.getOnlinePoints());	
			districtMember.setTotalPoints(detail.getPoints());		
			DistrictMemberQuery memberQuery = new DistrictMemberQuery();
			memberQuery.setVersion(districtMember.getVersion());
			memberQuery.setMemberId(districtMember.getMemberId());
			memberQuery.setBusdId(districtMember.getBusdId());
			districtMember.setVersion(districtMember.getVersion() + 1);
			if (baseMapper.update(districtMember, memberQuery.toQueryWrapper()) != 1) {
				throw new DragonException(ErrorCode.CONCURRENT_FAILURE);
			}
			log.debug("累计积分改为所计算收入积分总和，会员id={}，商圈id={}，现累计积分={}", districtMember.getMemberId(),
					districtMember.getBusdId(), detail.getPoints());
		}

	}
}